﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace Los.Barcode
{
    /*  Code syntax: [a..z]{4}:.+
     * 
     * 
    */

    public abstract class Interpreter
    {
        abstract internal string GetCode(object obj);
        abstract internal object GetObject(string code);
        abstract internal bool CanInterpret(object obj);

        protected IDictionary<string, string> GetParameters(string code)
        {
            string validity_check = "^[a-z]{4}:(.*)";
            Regex regex = new Regex(validity_check);
            var result = regex.Match(code);
            if (result.Success)
            {
                Dictionary<string, string> param = new Dictionary<string, string>();
                var param_str = result.Groups[1].Value.Split(new char[] {';'}, StringSplitOptions.RemoveEmptyEntries);
                foreach (var p in param_str)
                {
                    var pair = p.Split(new char[] { '=' });
                    if (pair.Length == 1)
                    {
                        param.Add(pair[0], "1");
                    }
                    if (pair.Length == 2)
                    {
                        param.Add(pair[0], pair[1]);
                    }
                }
                return param;

            }
            throw new Exception("Invalid code.");
        }

        static internal Interpreter GetInterpreter(string code)
        {
            string validity_check = "^([a-z]{4}):.*";
            // check validity
            Regex regex = new Regex(validity_check);
            var result = regex.Match(code);

            if (result.Success && (Registration.Instance.ContainsKey(result.Groups[1].Value)))
            {
                return Registration.Instance[result.Groups[1].Value];
            }

            throw new Exception("Invalid code.");
        }

        static internal Interpreter GetInterpreter(object obj)
        {
            var interpreter = Registration.Instance.Values.Where(x => x.CanInterpret(obj)).Take(1);
            if (interpreter.Count() > 0)
                return interpreter.First();
            return null;
        }

        static public object CreateObject(string code)
        {
            Interpreter ip = GetInterpreter(code);
            return ip.GetObject(code);
        }

        static public string CreateCode(object obj)
        {
            Interpreter ip = GetInterpreter(obj);
            return ip.GetCode(obj);
        }
    }

    internal class Registration : Dictionary<string, Interpreter>
    {
        static private Registration instance = new Registration();

        private Registration()
        {
            Add("rela", new RelationInterpreter());
        }

        static public Registration Instance
        {
            get { return instance; }
        }       

    }
}
